package com.kailing.bootBatch.thread;

import java.util.concurrent.Semaphore;

/**
 * <h3>partitionjob</h3>
 * <p>fb3</p>
 * 参考： https://www.cnblogs.com/heyu/articles/3669336.html
 * @author : hduong
 * @version : 1.0
 * @date : 2019-12-18 10:57
 **/
public class FooBar3 {
    private int n;
    //初始许可证: 为1 标识可以获取许可
    private Semaphore semaphore_foo = new Semaphore(1);
    //为0 标识不能获取许可 : 如果要从这里获取许可 将一直等待阻塞
    private Semaphore semaphore_bar = new Semaphore(0);

    public FooBar3(int n) {
        this.n = n;
    }

    public void foo() {

        for (int i = 0; i < n; i++) {
            //请求获得许可，若存在许可，则获得的同时许可数量减一，若不存在则阻塞进入等待状态
            //1.初始许可为1，可以获得许可，代码继续执行

            try {
                semaphore_foo.acquire();
                System.out.print("foo");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //释放许可，但必须在获得许可的前提下才能够释放，释放后许可数量加一
            semaphore_bar.release();
            //2.初始许可为0，释放许可必须要先获得许可，线程阻塞，进入步骤3
            //2.1 因步骤3.1获得许可，此时可以释放，(第一次交替执行结束)，从步骤1重新开始
        }
    }

    public void bar() {
        for (int j = 0; j < n; j++) {
            try {
                //3.此时许可数为0，阻塞等待(异常)，3.1获得释放的许可，代码继续执行
                semaphore_bar.acquire();
                System.out.print("bar");
                //4.释放许可，重新进入步骤3.1 4.1此时释放许可，线程阻塞，进入步骤2.1(参照步骤2)
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            semaphore_foo.release();
        }
    }

}
